package com.cloud.ebookreader.opf;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

import com.cloud.ebookreader.access.Metadata;
import com.cloud.ebookreader.access.TocEntry;

public class OpfParser {
	Logger logger = Logger.getLogger(this.getClass());
    final Metadata metadata = new Metadata();
    private final List<TocEntry> toc = new LinkedList<TocEntry>();
    
    private final Map<String, String> mime = new HashMap<String, String>();

    public Metadata getMetadata() {
        return metadata;
    }

    public void parse(InputStream in) throws SAXException, IOException {

        XMLReader xmlReader = XMLReaderFactory.createXMLReader();

        final Map<String, String> items = new HashMap<String, String>();
        
        

        xmlReader.setContentHandler(new ContentHandler() {

            boolean inMetadata = false;
            boolean inSpine = false;
            StringBuilder currentValue = new StringBuilder();
            Attributes currentAttributes;

            public void setDocumentLocator(Locator lctr) {
            }

            public void startDocument() throws SAXException {
            }

            public void endDocument() throws SAXException {
            }

            public void startPrefixMapping(String string, String string1) throws SAXException {
            }

            public void endPrefixMapping(String string) throws SAXException {
            }

            public void startElement(String string, String localName, String string2, Attributes atrbts) throws SAXException {
                currentAttributes = atrbts;
                currentValue = new StringBuilder();
                if (localName.equals("metadata")) {
                    inMetadata = true;
                }
                if (localName.equals("spine")) {
                    inSpine = true;
                }

            }

            public void endElement(String string, String localName, String string2) throws SAXException {
                logger.debug("Handle: " + localName);
                if (localName.equals("metadata")) {
                    inMetadata = false;
                }
                if (inMetadata) {
                    if (localName.equalsIgnoreCase("title")) {
                        metadata.setTitle(currentValue.toString());
                    }
                    if (localName.equalsIgnoreCase("creator")) {
                        metadata.setCreator(currentValue.toString());
                    }
                    if (localName.equalsIgnoreCase("publisher")) {
                        metadata.setPublisher(currentValue.toString());
                    }
                    if (localName.equalsIgnoreCase("language")) {
                        metadata.setLanguage(currentValue.toString());
                    }

                }
                if (localName.equalsIgnoreCase("item")) {
                    items.put(currentAttributes.getValue("id"), currentAttributes.getValue("href"));
                    mime.put(currentAttributes.getValue("href"), currentAttributes.getValue("media-type"));
                }

                if (localName.equalsIgnoreCase("itemref")) {
                    String id = currentAttributes.getValue("idref");
                    TocEntry entry = new TocEntry();
                    entry.setComponentName(items.get(id));
                    entry.setTitle(id);
                    getToc().add(entry);
                }


            }

            public void characters(char[] ch, int start, int length) throws SAXException {

                currentValue.append(new String(ch, start, length));
            }

            public void ignorableWhitespace(char[] chars, int i, int i1) throws SAXException {
                throw new UnsupportedOperationException("Not supported yet.");
            }

            public void processingInstruction(String string, String string1) throws SAXException {
                throw new UnsupportedOperationException("Not supported yet.");
            }

            public void skippedEntity(String string) throws SAXException {
                throw new UnsupportedOperationException("Not supported yet.");
            }
        });

        xmlReader.parse(new InputSource(in));

    }

    /**
     * @return the toc
     */
    public List<TocEntry> getToc() {
        return toc;
    }
    
    public Map<String, String> getMime(){
        return mime;
    }
}
